From e3dda81e47376665c0034fe0bcd45e35601470df Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Fri, 18 May 2018 11:02:04 +0200 Subject: [PATCH] babl: use hashtable approach in double reference Strictly speaking we should be doing the reference using conversions to R'G'B'A double and using the distance metric there; possibly getting a slight difference in result at comparison ties. In use GEGL ends up using both the really fast 8bit code paths and the quite fast floating point code paths that use 8bit hashtables for the lookup of conversion. Progress on bug #787237 missing fast-paths. --- babl/babl-palette.c | 154 ++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 92 deletions(-) diff --git a/babl/babl-palette.c b/babl/babl-palette.c index a22ea58..ca375c9 100644 --- a/babl/babl-palette.c +++ b/babl/babl-palette.c @@ -28,13 +28,11 @@ #define HASH_TABLE_SIZE 1111 -//#define SHOW_PATH - /* A default palette, containing standard ANSI / EGA colors * */ -static unsigned char defpal_data[4*16] = -{ +static unsigned char defpal_data[4*16] = +{ 0 ,0 ,0 ,255, 127,0 ,0 ,255, 0 ,127,0 ,255, @@ -77,6 +75,8 @@ babl_palette_reset_hash (BablPalette *pal) } } +#define BABL_IDX_FACTOR 255.5 + static int babl_palette_lookup (BablPalette *pal, int r, int g, int b, int a) { @@ -180,108 +180,92 @@ static BablPalette *default_palette (void) static void rgba_to_pal (Babl *conversion, - char *src, + char *src_b, char *dst, long n, void *dst_model_data) { + const Babl *space = babl_conversion_get_source_space (conversion); BablPalette **palptr = dst_model_data; - BablPalette *pal = *palptr; -#ifdef SHOW_PATH - fprintf (stderr, "d"); -#endif + BablPalette *pal; + assert (palptr); + pal = *palptr; + assert(pal); + while (n--) { - int idx; - - int best_idx = 0; - double best_diff = 100000; - double srcf[4]; + double *src_d = (void*) src_b; + unsigned char src[4]; int c; - for (c = 0; c < 4; c++) + for (c = 0; c < 3; c++) { - srcf[c] = ((double *) src)[c]; - if (srcf[c] < 0.0) - srcf[c] = 0.0; - if (srcf[c] > 1.0) - srcf[c] = 1.0; + if (src_d[c] >= 1.0f) + src[c] = 255; + else if (src_d[c] <= 0.0f) + src[c] = 0; + else + src[c] = babl_trc_from_linear (space->space.trc[0], + src_d[c]) * 255 + 0.5f; } + if (src_d[3] >= 1.0f) + src[3] = 255; + else if (src_d[3] <= 0.0f) + src[3] = 0; + else + src[3] = src_d[3] * 255 + 0.5f; - for (idx = 0; idxcount; idx++) - { - double diff; - double *palpx = ((double *)pal->data_double) + idx * 4; - - diff = (palpx[0] - srcf[0]) * (palpx[0] - srcf[0]) + - (palpx[1] - srcf[1]) * (palpx[1] - srcf[1]) + - (palpx[2] - srcf[2]) * (palpx[2] - srcf[2]); - if (diff <= best_diff) - { - best_diff = diff; - best_idx = idx; - } - } - - ((double *) dst)[0] = best_idx / 255.5; + ((double *) dst)[0] = + babl_palette_lookup (pal, src[0], src[1], src[2], src[3]) / + BABL_IDX_FACTOR; - src += sizeof (double) * 4; + src_b += sizeof (double) * 4; dst += sizeof (double) * 1; } + } static void rgba_to_pala (Babl *conversion, - char *src, + char *src_i, char *dst, long n, void *dst_model_data) { + const Babl *space = babl_conversion_get_destination_space (conversion); BablPalette **palptr = dst_model_data; - BablPalette *pal = *palptr; - -#ifdef SHOW_PATH - fprintf (stderr, "D"); -#endif + BablPalette *pal; + assert (palptr); + pal = *palptr; assert(pal); + while (n--) { - int idx; - - int best_idx = 0; - double best_diff = 100000; - double srcf[4]; - double alpha; + double *src_d = (void*) src_i; + unsigned char src[4]; int c; - for (c = 0; c < 4; c++) + for (c = 0; c < 3; c++) { - srcf[c] = ((double *) src)[c]; - if (srcf[c] < 0.0) - srcf[c] = 0.0; - if (srcf[c] > 1.0) - srcf[c] = 1.0; + if (src_d[c] >= 1.0f) + src[c] = 255; + else if (src_d[c] <= 0.0f) + src[c] = 0; + else + src[c] = babl_trc_from_linear (space->space.trc[0], + src_d[c]) * 255 + 0.5f; } + if (src_d[3] >= 1.0f) + src[3] = 255; + else if (src_d[3] <= 0.0f) + src[3] = 0; + else + src[3] = src_d[3] * 255 + 0.5f; - alpha = srcf[3]; - - for (idx = 0; idxcount; idx++) - { - double diff; - double *palpx = ((double *)pal->data_double) + idx * 4; - - diff = (palpx[0] - srcf[0]) * (palpx[0] - srcf[0]) + - (palpx[1] - srcf[1]) * (palpx[1] - srcf[1]) + - (palpx[2] - srcf[2]) * (palpx[2] - srcf[2]); - if (diff <= best_diff) - { - best_diff = diff; - best_idx = idx; - } - } - ((double *) dst)[0] = best_idx / 255.5; - ((double *) dst)[1] = alpha; + ((double *) dst)[0] = babl_palette_lookup (pal, src[0], src[1], src[2], + src[3]) / BABL_IDX_FACTOR; + ((double *) dst)[1] = src_d[3]; - src += sizeof (double) * 4; + src_i += sizeof (double) * 4; dst += sizeof (double) * 2; } } @@ -298,7 +282,7 @@ pal_to_rgba (Babl *conversion, assert(pal); while (n--) { - int idx = (((double *) src)[0]) * 255.5; + int idx = (((double *) src)[0]) * BABL_IDX_FACTOR; double *palpx; if (idx < 0) idx = 0; @@ -325,7 +309,7 @@ pala_to_rgba (Babl *conversion, assert(pal); while (n--) { - int idx = (((double *) src)[0]) * 255.5; + int idx = (((double *) src)[0]) * BABL_IDX_FACTOR; double alpha = (((double *) src)[1]); double *palpx; @@ -354,9 +338,7 @@ rgba_u8_to_pal (Babl *conversion, assert (palptr); pal = *palptr; assert(pal); -#ifdef SHOW_PATH - fprintf (stderr, "8"); -#endif + while (n--) { dst[0] = babl_palette_lookup (pal, src[0], src[1], src[2], src[3]); @@ -380,9 +362,6 @@ rgba_float_to_pal_a (Babl *conversion, pal = *palptr; assert(pal); -#ifdef SHOW_PATH - fprintf (stderr, "f"); -#endif while (n--) { float *src_f = (void*) src_b; @@ -428,9 +407,7 @@ rgba_float_to_pal (Babl *conversion, assert (palptr); pal = *palptr; assert(pal); -#ifdef SHOW_PATH - fprintf (stderr, "F"); -#endif + while (n--) { float *src_f = (void*) src_b; @@ -630,7 +607,6 @@ const Babl *babl_new_palette (const char *name, "chroma", NULL); alpha = babl_component ("A"); - model = babl_model_new ("name", name, component, alpha, NULL); palptr = malloc (sizeof (void*)); *palptr = default_palette ();; @@ -678,30 +654,24 @@ const Babl *babl_new_palette (const char *name, "data", palptr, NULL ); - babl_conversion_new ( f_pal_u8, f_pal_a_u8, "linear", conv_pal8_pala8, NULL ); - babl_conversion_new ( f_pal_a_u8, f_pal_u8, "linear", conv_pala8_pal8, NULL ); - - babl_conversion_new ( f_pal_u8, babl_format ("R'G'B'A u8"), "linear", pal_u8_to_rgba_u8, "data", palptr, NULL); - - babl_conversion_new ( f_pal_a_u8, babl_format ("R'G'B'A u8"), -- 2.30.2